package KK.net
{
	import KK.Data.ProtocolData;
	import KK.EMVC.Control.Control;
	import KK.GameBase.IMessageFollowers;
	import KK.GameBase.IMessageQueue;
	import KK.Global.Game;
	import KK.System.System;
	import KK.net.Command.CommandID;
	import KK.net.Data.Head;
	import KK.net.Event.SocketEvent;
	
	import Protocol.EProtocol;
	import Protocol.SLogin;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.Socket;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	
	public class SocketManager extends Control
	{
		
		static public const CONN_LOGIN:int=0;
		static public const CONN_LOGIC:int=1;
		
		static private var instance:SocketManager;
		
		private var conn:Socket;
		private var host:String;
		private var port:uint;
		
		private var buff:ByteArray;//缓存 
		
		private var state:int;
		public function SocketManager(singleton:Singleton)
		{
			//TODO: implement function
			super();
			
			if(instance){
				throw new Error("class is singleton ,using Instance get Instance");
			}
			instance=this;
			init();
		}
		
		private function init():void{
			conn=new Socket;
			buff=ProtocolData.Creator();
			conn.addEventListener(ProgressEvent.SOCKET_DATA,OnData);
			conn.addEventListener(Event.CONNECT,OnConnect);
			conn.addEventListener(IOErrorEvent.IO_ERROR,OnError);
			conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR,OnError);
			conn.addEventListener(Event.CLOSE,OnClose);
			
		}
		
		
		/**
		 *  
		 * @param event
		 * @return 
		 * 
		 */
		override public function BindEvent(_event:IMessageQueue):Boolean{
			var result:Boolean=super.BindEvent(_event);
			AttentionMessage(SocketEvent.SEND,onSend);
//			ProxyManager(CommandID.IC_LOGIC_LOGIN,onConnLogic);
			return result;
		}
		
		/**
		 * 发送  
		 * @param event
		 * 
		 */
		protected function onSend(event:SocketEvent):void{
			var head:Head=new Head();
			head.protocolType=0;
			head.protocolID=event.CommandID;
			head.len=event.Data.length;
			var byte:ByteArray=ProtocolData.Creator();
			Game.BugMSG("发送protocol ID: "+head.protocolID);
			head.Serialize(byte);
			byte.writeBytes(event.Data,0,event.Data.length);
			Send(byte);
//			Send(event.Data);
			
		}
		/**
		 * 登陆  
		 * 
		 */
		protected function Login():void{
			Game.OnProcess(CommandID.IC_LOGIN);
		}
		
		/**
		 * 逻辑服务器登陆  
		 * 
		 */
		protected function logicLogin():void{ 
			Game.OnProcess(CommandID.IC_LOGIC_LOGIN);
		}
		 
		/**
		 * 关闭  
		 * @param event
		 * 
		 */
		private function OnClose(event:Event):void{ 
			LogInfo("Socket 断开连接");
		}
		
		/**
		 * 逻辑登陆  
		 * 
		 *//*
		private function onConnLogic():void{
			state=CONN_LOGIC;
		}*/
		/**
		 * 错误响应  
		 * @param event
		 * 
		 */
		private function OnError(event:Event):void{
			var msg:String="";
			switch(event.type){
				case IOErrorEvent.IO_ERROR:
					msg=("连接服务器失败 ,地址错误 Socket连接失败");
					
					break;
				case SecurityErrorEvent.SECURITY_ERROR: 
					msg=("安全沙箱出错 socket连接失败 ");
					break;
				default:
					
					break;
			}
			 
			LogInfo(msg);
		}
		/**
		 * 连接成功  
		 * @param event
		 * 
		 */
		private function OnConnect(event:Event):void{
			LogInfo("连接成功,状态是 ：",state); 
			switch(state){
				case CONN_LOGIN:
					Login();
					break;
				case CONN_LOGIC:
					logicLogin();
					break;
			}
			 
		}
		
		/**
		 * 发送  
		 * @param byte
		 * 
		 */
		private function Send(byte:ByteArray):void{ 
			conn.writeBytes(byte,0,byte.length);
			byte.position=0;
			conn.flush();
			LogInfo(System.ByteToHEX(byte));
		}
		/**
		 * 数据流 
		 * @param event
		 * 
		 */
		private function OnData(event:ProgressEvent):void{
			Recv();
		}
		
		private function Recv():void{
			
			conn.readBytes(buff,buff.length,conn.bytesAvailable);
			buff.length>=Head.LEN&&ParserHead();
			
		}
		
		/**
		 * 解析包头  
		 * 
		 */
		private function ParserHead():void{
			var head:Head=new Head();
			head.Unserialize(buff);
			LogInfo("收到数据包 id：",head.protocolID);
			Game.BugMSG("收到数据包 id："+head.protocolID);
			if(buff.length>=head.len){
				var byte:ByteArray=ProtocolData.Creator();
				const position:uint=head.len-Head.LEN;
				byte.writeBytes(buff,Head.LEN,buff.length-Head.LEN); 
				ProxyManager.OnMessage(head,byte);
				
				buff.clear();
				buff.writeBytes(byte,position,byte.length-position);
			}
		}
		
		/**
		 * 开始连接  
		 * 
		 */
		public function TestConnect(addr:String="192.168.1.254:10000"):void{
			
			Game.LoginAddress=addr;
			Game.OpenID="test";
			connect(Game.LoginAddress);
		}
		
		/**
		 * 连接服务器  
		 * @param host
		 * @param port
		 * 
		 */
		public function connect(addr:String):void{
			if(addr&&addr.length>0){
				var arr:Array=addr.split(":");
				arr.length<2&&LogInfo("地址格式错误 ");
			}else{ 
				LogError("网络地址错误 ");
			} 
			conn.connect(arr[0],arr[1]);
		}
		
		
		/**
		 * 获取  
		 * @return 
		 * 
		 */
		static public function get Instance():SocketManager{
			if(!instance){
				new SocketManager(new Singleton);
			}
			
			return instance;
		}
	}
}
class Singleton{
	
}